// ToDo 1 : changed name or group processing
// ToDo 2 : addressee == myself processing

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>
#include <QDateTime>
#include <QLayout>
#include <QMetaType>
#include <QIcon>
#include <QDesktopServices>
#include <QUrl>
#include <QInputDialog>

#include "Define.h"
#include "ClientManager.h"
#include "UDPSender.h"
#include "UDPReceiver.h"
#include "FileManager.h"
#include "MessageManager.h"
#include "TextEditor.h"
#include "FileSelect.h"
#include "MyProgressBar.h"
#include "Setting.h"
#include "ConfigManager.h"
#include "IPName.h"
#include "LogManager.h"
#include "GroupList.h"

#ifdef Q_WS_WIN
#include "hooklib.h"
#endif

#define TIMER_INTERVAL 1000
#define TIMER_SHOW_MESSAGE 3

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	_udpSender = new UDPSender;
	_fileSelect = new FileSelect;
	_fileManager = new FileManager;
	_msgManager = new MessageManager;
	_textEditor = new TextEditor;
	_setting = new Setting;
	_ipName = new IPName;
	_logManager = new LogManager;
	_groupList = new GroupList;
	if (_fileManager->Initialize() &&
		_msgManager->Initialize() &&
		_setting->Initialize() &&
		_ipName->Initialize() &&
		InitStatusBar() &&
		InitTimer())
	{

		_dec = QTextCodec::codecForName("EUC-KR");
		_enc = QTextCodec::codecForName("EUC-KR");

		_logManager->Initialize();
		InitWidget();
		InitActionShortcut();
		_fileSelect->Initialize(true);
		_fileSelect->hide();
		_setting->hide();
		_udpSender->Initialize();

		qRegisterMetaType<FileKey>("FileKey");
		qRegisterMetaType<QHostAddress>("QHostAddress");

		// connect slots..
		connect(UDP_RECEIVER, SIGNAL(sigDatagramReceived(UDPPacket*)),
				this, SLOT(ProcessUDPPacket(UDPPacket*)), Qt::QueuedConnection);
		connect(_fileManager, SIGNAL(sigMakeProgressBar(FileKey,long long)),
				this, SLOT(CreateProgressBar(FileKey,long long)), Qt::QueuedConnection);
		connect(_fileManager, SIGNAL(sigOnProcessing(FileKey,int)),
				this, SLOT(UpdateProgressBar(FileKey,int)), Qt::QueuedConnection);
//		connect(_fileManager, SIGNAL(sigDestroyProgressBar(FileKey)),
//				this, SLOT(RemoveProgressBar(FileKey)));
		connect(_fileManager, SIGNAL(sigNotice(QString)),
				this, SLOT(OnError(QString)), Qt::QueuedConnection);
		connect(this, SIGNAL(sigAddSendTask(QHostAddress,QString)),
				_fileManager, SLOT(AddSendTask(QHostAddress,QString)),Qt::QueuedConnection);
		connect(_fileManager, SIGNAL(sigEnableProgressBarButton(FileKey)),
				this, SLOT(EnableProgressBarButton(FileKey)), Qt::QueuedConnection);
		connect(_msgManager, SIGNAL(sigMesasgeReceived(QByteArray)),
				this, SLOT(ProcessTCPPacket(QByteArray)), Qt::QueuedConnection);
		connect(_msgManager, SIGNAL(sigNotice(QString)),
				this, SLOT(OnError(QString)), Qt::QueuedConnection);
		connect(_fileSelect, SIGNAL(sigFileSeleted(QString, QString)),
				this, SLOT(OnFileSelected(QString, QString)));
		connect(_setting, SIGNAL(sigNetworkConfigChanged(int, QString)), this, SLOT(OnNetworkConfigChange(int, QString)));
		connect(_setting, SIGNAL(sigLogDeleted()), this, SLOT(OnRemoveAllLog()));
		connect(_ipName, SIGNAL(sigAddSendList(QString)), this, SLOT(AddSendListFromIPName(QString)));
		connect(_groupList, SIGNAL(sigGroupSelected(QString)), this, SLOT(OnCustomGroupSelected(QString)));

		_udpSender->SendDatagram(QString(';' + CONFIG_MANAGER->GetGroupName()).toAscii(), CONFIG_MANAGER->GetNetworkPort());

		_isfileSend = false;
		_exit = false;
		_fixedView = false;
		_newMsgCnt = 0;
	}
	else
		qDebug() << "MainWindow::Initialize() failed";
}

MainWindow::~MainWindow()
{
#ifdef Q_WS_WIN
	if (_hookInstalled)
		UninstallHook();
	_trayIcon->hide();
#endif
}

#ifdef Q_WS_WIN
bool MainWindow::winEvent(MSG *message, long *result)
{
	if (message->hwnd == winId() &&
		message->message == KEY_MESSAGE &&
		CONFIG_MANAGER->IsShortcutEnable())
	{
		if (isHidden())
		{
			show();
			_trayIcon->hide();
		}
		else
		{
			hide();
			_trayIcon->show();
		}
	}
	return false;
}

void MainWindow::TrayActivated(QSystemTrayIcon::ActivationReason reason)
{
	switch(reason)
	{
		case QSystemTrayIcon::DoubleClick:
			show();
			_trayIcon->hide();
			break;
		default:
			break;
	}
}

#endif

void MainWindow::closeEvent(QCloseEvent *event)
{

#ifdef Q_WS_WIN
	if (_exit)
	{
		_udpSender->SendDatagram(QString(";-" + CONFIG_MANAGER->GetGroupName()).toAscii(), CONFIG_MANAGER->GetNetworkPort());
		if (_textEditor != NULL)
			delete _textEditor;
		if (_logManager != NULL)
			delete _logManager;
		event->accept();
		delete ui;
	}
	else
	{
		_trayIcon->show();
		hide();
		event->ignore();
	}
#else
	_udpSender->SendDatagram(QString(";-" + CONFIG_MANAGER->GetGroupName()).toAscii(), CONFIG_MANAGER->GetNetworkPort());
	if (_textEditor != NULL)
		delete _textEditor;
	if (_logManager != NULL)
		delete _logManager;
	event->accept();
	delete ui;
#endif
}

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
	QMenu menu(this);
	menu.addAction(_actionOpenDownloadFolder);
	menu.addAction(_actionOpenLogFolder);
	menu.addAction(_actionSaveWindowSize);
	menu.exec(event->globalPos());
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
	if (event->mimeData()->hasUrls())
	{
		QList<QUrl> url = event->mimeData()->urls();
		QFileInfo f(url.first().toLocalFile());
		if (!f.isDir())
		{
			event->acceptProposedAction();
			qDebug() << f.fileName();
		}
	}
}

void MainWindow::dropEvent(QDropEvent *event)
{
	QFileInfo f(event->mimeData()->urls().first().toLocalFile());
	OnFileSelected(f.filePath(), f.fileName());
}

bool MainWindow::InitStatusBar()
{
	_labelClientCount = new QLabel("");
	_labelMyInfo = new QLabel("");
	_labelCurrentTime = new QLabel("");
	_labelCurrentStatus = new QLabel("");

	if (_labelClientCount != NULL &&
		_labelMyInfo != NULL &&
		_labelCurrentTime != NULL &&
		_labelCurrentStatus != NULL)
	{
		_labelClientCount->setText("0");
		_labelMyInfo->setText(CONFIG_MANAGER->GetGroupName());
		_labelCurrentStatus->setText("Initialized.");

		_labelClientCount->setAlignment(Qt::AlignCenter);
		_labelMyInfo->setAlignment(Qt::AlignCenter);
		_labelCurrentTime->setAlignment(Qt::AlignCenter);
		_labelCurrentStatus->setAlignment(Qt::AlignCenter);

		ui->statusBar->addWidget(_labelClientCount);
		ui->statusBar->addWidget(_labelMyInfo, 1);
		ui->statusBar->addWidget(_labelCurrentTime, 2);
		ui->statusBar->addWidget(_labelCurrentStatus, 3);
		ui->statusBar->addWidget(&_progressButton);

		return true;
	}
	else
	{
		OnError("MainWindow::InitStatusBar() : Not enough memory");
		return false;
	}
}

bool MainWindow::InitTimer()
{
	qDebug() << "InitTimer()";
	_timer = new QTimer;
	if (_timer != NULL)
	{
		_timer->setInterval(TIMER_INTERVAL);
		_timer->start();
		connect(_timer, SIGNAL(timeout()), this, SLOT(OnEverySecond()));
		return true;
	}
	else
	{
		OnError("MainWindow::InitTimer() : Not enough memory");
		return false;
	}
}

void MainWindow::InitWidget()
{
	ui->comboBox->addItem("ALL");
	ui->comboBox->setCurrentIndex(0);
	ui->list_connect->setSortingEnabled(true);
	ui->textEdit_receive->setReadOnly(true);

	connect(ui->list_connect, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(on_button_insert_clicked()));
	connect(ui->list_send, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(on_button_remove_clicked()));

	int rxLogCnt = _logManager->GetLogCount(false);
	int txLogCnt = _logManager->GetLogCount(true);
	ManageLogWidget(true, txLogCnt, txLogCnt, false);
	ManageLogWidget(false, rxLogCnt, rxLogCnt, true);

	ui->list_sendFile->hide();
	ui->list_fileList->hide();
	connect(&_progressButton, SIGNAL(clicked()), this, SLOT(OnProgressButtonClicked()));

	//icon
	setWindowIcon(QIcon("../img/icon.png"));

	setGeometry(CONFIG_MANAGER->GetWindowSize());
	setAcceptDrops(true);


	#ifdef Q_WS_WIN
	//Tray icon setting...
		_trayIcon = new QSystemTrayIcon;
		if (InstallHook(winId()) && _trayIcon != NULL)
		{
			_quitAction = new QAction(tr("Quit"), this);
			connect(_quitAction, SIGNAL(triggered()), this, SLOT(ExitMenuClicked()));

			_trayIconMenu = new QMenu;
			_trayIconMenu->addAction(_quitAction);
			_trayIcon = new QSystemTrayIcon(this);
			_trayIcon->setContextMenu(_trayIconMenu);
			_trayIcon->setIcon(QIcon("../img/icon.png"));
			connect(_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
					this, SLOT(TrayActivated(QSystemTrayIcon::ActivationReason)));
			_trayIcon->show();
			_hookInstalled = true;

		}
	//always view on the top
		SetWindowPos(winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
	#endif
}

void MainWindow::InitActionShortcut()
{
	//action

	//log folder action
	_actionOpenDownloadFolder = new QAction(tr("Open Download Folder(Ctrl+E)"), this);
	_actionOpenLogFolder = new QAction(tr("Open Log Folder(Ctrl+L)"), this);
	_actionSaveWindowSize = new QAction(tr("Save Current Window Size"), this);
	connect(_actionOpenDownloadFolder, SIGNAL(triggered()), this, SLOT(OnOpenDirectory()));
	connect(_actionOpenLogFolder, SIGNAL(triggered()), this, SLOT(OnOpenDirectory()));
	connect(_actionSaveWindowSize, SIGNAL(triggered()), this, SLOT(OnSaveWindowSize()));
	connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(ExitMenuClicked()));
	connect(ui->actionSetting, SIGNAL(triggered()), this, SLOT(SettingMenuClicked()));

	//shortcut
	_shortcutSend = new QShortcut(QKeySequence("Ctrl+S"), this);
	_shortcutReply = new QShortcut(QKeySequence("Ctrl+R"), this);
	_shortcutOpenDownLoadFolder = new QShortcut(QKeySequence("Ctrl+E"), this);
	_shortcutOpenLogFolder = new QShortcut(QKeySequence("Ctrl+L"), this);
	connect(_shortcutSend, SIGNAL(activated()), this, SLOT(on_button_sSend_clicked()));
	connect(_shortcutReply, SIGNAL(activated()), this, SLOT(on_button_reply_clicked()));
	connect(_shortcutOpenDownLoadFolder, SIGNAL(activated()), this, SLOT(OnOpenDirectory()));
	connect(_shortcutOpenLogFolder, SIGNAL(activated()), this, SLOT(OnOpenDirectory()));
}

void MainWindow::ProcessUDPPacket(UDPPacket *packet)
{
	QString rawData = _dec->toUnicode(packet->dgram.data(), packet->dgram.size());
	Notice mode;
	int startPos = 0;
	if (rawData.at(0) == ';')
	{
		if (rawData.at(1) == '-')
		{
			mode = NoticeDisconnect;
			startPos += 2;
		}
		else
		{
			mode = NoticeConnect;
			startPos += 1;
		}
	}
	else
		mode = NoticeResponse;

	int colonIdx = rawData.indexOf(QChar(':'));
	QString group = "", name = "";
	if (colonIdx != -1)
	{
		name = rawData.section(':', -1);
		QString temp = rawData.section(':', -2, -2);
		group = temp.right(temp.length() - startPos);
	}
	else
	{
		group = "unknown";
		name = rawData.right(rawData.length() - startPos);
	}
	QString currentComboText = ui->comboBox->currentText();
	bool modify = false, add = true;

	if (mode != NoticeDisconnect)
	{
		if (mode == NoticeConnect)
		{
			if (CLIENT_MANAGER->UpdateClient(group, name, packet->addr))
			{

				QString preName, preGroup;
				if (CLIENT_MANAGER->GetClientInfo(packet->addr, preName, preGroup))
				{
					UpdateConnectList(preGroup, preName, currentComboText, CLIENT_MANAGER->GetGroupMemberCount(preGroup), false);
					modify = true;
				}
			}
			else if (CLIENT_MANAGER->AddClient(group, name, packet->addr))
				modify = true;

			if (!CONFIG_MANAGER->IsMyInfo(group, name))
				_udpSender->SendDatagram(CONFIG_MANAGER->GetGroupName().toAscii(), packet->addr, CONFIG_MANAGER->GetNetworkPort());
		}
		else if (mode == NoticeResponse)
		{
			if (CLIENT_MANAGER->AddClient(group, name, packet->addr))
				modify = true;
		}
	}
	else
	{
		if (CLIENT_MANAGER->RemoveClient(group, name))
		{
			modify = true;
			add = false;
		}
	}
	if (modify)
		UpdateConnectList(group, name, currentComboText, CLIENT_MANAGER->GetGroupMemberCount(group), add);
	delete packet;
}

void MainWindow::ProcessTCPPacket(QByteArray stream)
{
	_newMsgCnt++;
	ui->label_newMsg->setText(QString::number(_newMsgCnt));
	PutMessage(stream, true, false);
#ifdef Q_WS_WIN
	if (isHidden())
	{
		show();
		_trayIcon->hide();
	}
#endif
}


void MainWindow::OnError(QString errorString)
{
	_labelCurrentStatus->setText(errorString);
	_lastMsgReceiveTime = QTime::currentTime().addSecs(TIMER_SHOW_MESSAGE);
}

void MainWindow::OnFileSelected(QString filepath, QString fileName)
{
	ui->list_sendFile->show();
	if (ui->list_sendFile->count())
		ui->list_sendFile->clear();
	ui->list_sendFile->addItem(QString::fromUtf8("[첨부] ") + fileName);
	_filePath = filepath;
	_fileName = fileName;
	_isfileSend = true;
}

void MainWindow::CreateProgressBar(FileKey key, long long size)
{
	if (!_barMap.contains(key))
	{
		QListWidgetItem *newItem = new QListWidgetItem;
		MyProgressBar *newBar = new MyProgressBar(key, size);
		if (newBar != NULL && newItem != NULL)
		{
			newBar->Initialize();
			ui->list_fileList->addItem(newItem);
			ui->list_fileList->setItemWidget(newItem, newBar);
			connect(newBar, SIGNAL(sigDestroyProgressBar(FileKey)), this, SLOT(RemoveProgressBar(FileKey)));
			newBar->show();
			_mutex.lock();
			_barMap.insert(key, newBar);
			_mutex.unlock();
		}
		else
			qDebug() << "FileTransferProgressWindow::CreateProgressBar() : Not enough memory";
	}
	else
		qDebug() << "Progress bar is already exist..";
}

void MainWindow::UpdateProgressBar(FileKey key, int bytes)
{
	if (_barMap.contains(key))
		_barMap.value(key)->SetValue(bytes);
	else
		qDebug() << "MainWindow::UpdateProgressBar : undefined key"
				<< key.GetAddress()
				<< key.GetFileName()
				<< key.GetMode();
}

void MainWindow::RemoveProgressBar(FileKey key)
{
	if (_barMap.contains(key))
	{
		bool find = false;
		for (int i = 0; i < ui->list_fileList->count() && !find; i++)
		{
			QListWidgetItem *item = ui->list_fileList->item(i);
			find = (_barMap.value(key) == ui->list_fileList->itemWidget(item));
			if (find)
			{
				ui->list_fileList->removeItemWidget(item);
				ui->list_fileList->takeItem(i);

				_mutex.lock();
				_barMap.remove(key);
				_mutex.unlock();
			}
		}
	}
	else
		qDebug() << "MainWindow::RemoveProgressBar() : undefined key";
}

void MainWindow::EnableProgressBarButton(FileKey key)
{
	if (_barMap.contains(key))
		_barMap.value(key)->EnableButton();
}

void MainWindow::AddSendListFromIPName(QString str)
{
	bool found = false;
	for (int i = 0; i < ui->list_send->count() && !found; i++)
		found = (ui->list_send->item(i)->text() == str);
	if (!found)
		ui->list_send->addItem(str);
}

void MainWindow::OnNetworkConfigChange(int prePort, QString preName)
{
	_udpSender->SendDatagram(QString(";-" + preName).toAscii(), prePort);
	on_button_refresh_clicked();
}

void MainWindow::OnRemoveAllLog()
{
	_logManager->DeleteAllLog();
	ManageLogWidget(true, 0, _logManager->GetLogCount(true), false);
	ManageLogWidget(false, 0, _logManager->GetLogCount(false), false);
}

void MainWindow::OnOpenDirectory()
{
	QObject *s = sender();
	if (s != NULL)
	{
		QDir dir;
		QString path;
		if (s == _shortcutOpenDownLoadFolder || s == _actionOpenDownloadFolder)
			dir.setPath(CONFIG_MANAGER->GetDownloadPath());
		else if (s == _shortcutOpenLogFolder || s == _actionOpenLogFolder)
			dir.setPath(CONFIG_MANAGER->GetLogPath());
	#ifdef Q_WS_WIN
		path = QDir::toNativeSeparators(dir.absolutePath());
	#else
		path = dir.absolutePath();
	#endif
		QDesktopServices::openUrl(QUrl("file:///" + path));
	}
}

void MainWindow::OnSaveWindowSize()
{
	CONFIG_MANAGER->SetWindowSize(width(), height());
	OnError("Window size saved");
}

void MainWindow::OnCustomGroupSelected(QString gName)
{
	qDebug() << "OnCustomGrupSelected()";
	ui->list_send->clear();
	QStringList list;
	if (CONFIG_MANAGER->GetSavedMemberList(gName, list))
	{
		for (int i = 0; i < list.count(); i++)
			ui->list_send->addItem(QString::fromUtf8(list.at(i).toAscii().data(), list.at(i).length()));
	}
}

void MainWindow::OnEverySecond()
{
	if (_lastMsgReceiveTime <= QTime::currentTime() &&
		!_labelCurrentStatus->text().isEmpty())
	{
		_labelCurrentStatus->clear();
	}

	_labelCurrentTime->setText(QDateTime::currentDateTime().toString("yyyy/MM/dd(ddd)APhh:mm:ss"));
}

bool MainWindow::DeleteItemInList(QString str)
{
	bool deleted = false;
	for (int i = 0; i < ui->list_connect->count() && !deleted; i++)
	{
		if (ui->list_connect->item(i)->text() == str && !str.isEmpty())
		{
			ui->list_connect->takeItem(i);
			deleted = true;
		}
	}
	return deleted;
}

bool MainWindow::IsAlreadyExistInSendList(QString groupName)
{
	bool exist = false;
	for (int i = 0; i < ui->list_send->count() && !exist; i++)
	{
		if (ui->list_send->item(i)->text() == groupName)
			exist = true;
	}
	return exist;
}

void MainWindow::RefreshWidget()
{
	_labelClientCount->setText("0");
	int comboItems = ui->comboBox->count();
	for (int i = comboItems-1; i > 0; i--)
		ui->comboBox->removeItem(i);
	ui->comboBox->setCurrentIndex(0);
	ui->label_memCnt->setText("0");
	ui->list_connect->clear();
	_labelMyInfo->setText(CONFIG_MANAGER->GetGroupName());
}

void MainWindow::UpdateConnectList(QString group, QString name, QString currentGroupText, int gCnt, bool add)
{
	bool curGroup = (currentGroupText == group);
	bool all = (currentGroupText.contains("ALL"));

	if (add)
	{
		if (all)
			ui->list_connect->addItem(group + ':' + name);
		else if (curGroup)
			ui->list_connect->addItem(name);
		int memCnt = ui->label_memCnt->text().toInt();
		ui->label_memCnt->setText(QString::number(++memCnt));

		if (gCnt == 1)
			ui->comboBox->addItem(group);
	}
	else
	{
		QString str = "";
		//Delete..
		if (all || curGroup)
		{
			if (all)
				str = group + ':' + name;
			else if (curGroup)
				str = name;
			DeleteItemInList(str);
		}
		if (gCnt == 0)
		{
			ui->comboBox->removeItem(ui->comboBox->findText(group));
			on_comboBox_activated("ALL");
		}
	}
	_labelClientCount->setText(QString::number(CLIENT_MANAGER->GetClientCount()));
}

bool MainWindow::RemoveFileList(FileKey key)
{
	QListWidgetItem *item = new QListWidgetItem;
	bool stop = false;
	for (int i = 0; i < ui->list_fileList->count() && !stop; i++)
	{
		item = ui->list_fileList->item(i);
		stop = (_barMap.value(key) == ui->list_fileList->itemWidget(item));
		if (stop)
			ui->list_fileList->removeItemWidget(item);
	}
	return stop;
}

void MainWindow::ManageLogWidget(bool isTx, int curIdx, int sum, bool putMsg)
{
	QPushButton *previous = new QPushButton;
	QPushButton *first = new QPushButton;
	QPushButton *next = new QPushButton;
	QPushButton *latest = new QPushButton;
	QPushButton *del = new QPushButton;
	QPushButton *delAll = new QPushButton;
	QLabel *idxLabel = new QLabel;
	QLabel *sumLabel = new QLabel;
	QTextEdit *message = new QTextEdit;
	if (isTx)
	{
		previous = ui->button_sPrevious;
		first = ui->button_sFirst;
		next = ui->button_sNext;
		latest = ui->button_sLatest;
		del = ui->button_sDelete;
		idxLabel = ui->label_sendIndex;
		sumLabel = ui->label_sendSum;
		message = ui->textEdit_send;
		delAll = ui->button_sDeleteAll;
	}
	else
	{
		previous = ui->button_rPrevious;
		first = ui->button_rFirst;
		next = ui->button_rNext;
		latest = ui->button_rLatest;
		del = ui->button_rDelete;
		idxLabel = ui->label_rcvIndex;
		sumLabel = ui->label_rcvSum;
		message = ui->textEdit_receive;
		delAll = ui->button_rDeleteAll;
	}
	if (previous != NULL &&	first != NULL && next != NULL && latest != NULL &&
		del != NULL && idxLabel != NULL && sumLabel != NULL && message != NULL && delAll != NULL)
	{

		if (sum >= 1)
			delAll->setEnabled(true);
		else
			delAll->setDisabled(true);

		del->setEnabled(true);
		if (curIdx == 0)
		{
			previous->setDisabled(true);
			first->setDisabled(true);
			next->setDisabled(true);
			latest->setDisabled(true);
			del->setDisabled(true);
		}
		else if (curIdx == sum)
		{
			next->setDisabled(true);
			latest->setDisabled(true);
			if (sum <= 1)
			{
				previous->setDisabled(true);
				first->setDisabled(true);
			}
			else
			{
				previous->setEnabled(true);
				first->setEnabled(true);
			}
		}
		else if (curIdx == 1)
		{
			previous->setDisabled(true);
			first->setDisabled(true);
			if (sum <= 1)
			{
				next->setDisabled(true);
				latest->setDisabled(true);
			}
			else
			{
				next->setEnabled(true);
				latest->setEnabled(true);
			}
		}
		else
		{
			previous->setEnabled(true);
			first->setEnabled(true);
			next->setEnabled(true);
			latest->setEnabled(true);
		}

		idxLabel->setText(QString::number(curIdx));
		sumLabel->setText(QString::number(sum));
		if (putMsg)
		{
			if (curIdx > 0)
			{
				PutMessage(QByteArray(_logManager->GetLog(isTx, curIdx).toAscii()), false, isTx);
			}
		}
		else
		{
			if (!_fixedView)
				message->clear();
//			else
//				PutMessage(QByteArray(_logManager->GetLog(isTx, curIdx).toAscii()), false, isTx);
		}
	}
}

void MainWindow::PutMessage(QByteArray stream, bool log, bool isTx)
{
	QString message = "";
	char *rawData = new char [stream.length() + 1];
	if (rawData != NULL)
	{
		memcpy(rawData, stream.data(), stream.length());
		rawData[stream.length()] = '\0';

		char *from = rawData;
		char *dateTime = strchr(rawData, '\n');
		if (dateTime != NULL)
		{
			//*dateTime++ = ')';
			*dateTime++ = '\0';
			char *to = strchr(dateTime, '\n');
			if (to != NULL)
			{
				*to++ = ')';
				*to++ = '\0';
				to = strchr(to, ':');
				if (to != NULL)
				{
					to++;
					char *msg = strchr(to, '\n');
					if (msg != NULL)
					{
						*msg++ = '\0';
						message = QString("%1\n%2\n%3").
								  arg(_dec->toUnicode(from, strlen(from))).
								  arg(_dec->toUnicode(dateTime, strlen(dateTime))).
								  arg(_dec->toUnicode(msg, strlen(msg)));
						if (!_fixedView)
						{
							if (isTx)
							{
								ui->list_sWith->clear();
								QListWidgetItem *item = new QListWidgetItem(_dec->toUnicode(to, strlen(to)));
								item->setForeground(Qt::white);
								item->setBackground(Qt::black);
								ui->list_sWith->addItem(item);
//								ui->list_sWith->addItem(_dec->toUnicode(to, strlen(to)));
								ui->textEdit_send->setText(QString(_dec->toUnicode(msg)).remove("---------------------------\n"));
							}
							else
							{
								ui->list_with->clear();
								QListWidgetItem *item = new QListWidgetItem(_dec->toUnicode(to, strlen(to)));
								item->setForeground(Qt::white);
								item->setBackground(Qt::black);
								ui->list_with->addItem(item);
								ui->textEdit_receive->setText(message);
							}
						}

						if (log)
						{
							//AddLog..
							QByteArray logData = _enc->fromUnicode(TEXT_EDITOR->MessageTextProcessing(false,
																				 _dec->toUnicode(msg, strlen(msg)),
																				 _dec->toUnicode(from, strlen(from)),
																				 _dec->toUnicode(to, strlen(to)),
																				 ""));

							int exceedCnt = _logManager->GetLogCount(false) - CONFIG_MANAGER->GetLogCapacity() + 1;
							if (_logManager->AddLog(QString(logData), false))
							{
								int sumIdx = _logManager->GetLogCount(false);
								if (!_fixedView)
									ManageLogWidget(false, sumIdx, sumIdx, true);
								else
								{
									//Todo : add log when fixed status
									ui->label_rcvSum->setText(QString::number(sumIdx));

									//Todo : add log when fixed status
									if (exceedCnt >= 1)
									{
										int idx = ui->label_rcvIndex->text().toInt();
										idx -= exceedCnt;
										if (idx < 1)
											idx = 1;
										ui->label_rcvIndex->setText(QString::number(idx));
									}
								}
							}
							else
								OnError("Add log failed");
						}
					}
				}
			}
		}
		delete [] rawData;
	}
}

void MainWindow::on_button_insert_clicked()
{
	QListWidgetItem *item = ui->list_connect->currentItem();
	if (item != NULL)
	{
		QString insertItem;
		if (ui->comboBox->currentIndex() != 0)
			insertItem = RESPONSE(ui->comboBox->currentText(), item->text());
		else
			insertItem = item->text();
		if (!IsAlreadyExistInSendList(insertItem))
			ui->list_send->addItem(insertItem);
		else
			QMessageBox::warning(this, "warning", "duplicate user");
	}
}

void MainWindow::on_button_insertAll_clicked()
{
	bool allseleted = false;
	if (ui->comboBox->currentIndex() == 0)
		allseleted = true;
	QString insertItem;
	for (int i = 0; i < ui->list_connect->count(); i++)
	{
		if (!allseleted)
			insertItem = RESPONSE(ui->comboBox->currentText(), ui->list_connect->item(i)->text());
		else
			insertItem = ui->list_connect->item(i)->text();
		if (!IsAlreadyExistInSendList(insertItem))
			ui->list_send->addItem(insertItem);
	}
}

void MainWindow::on_button_remove_clicked()
{
	int index = ui->list_send->currentRow();
	ui->list_send->takeItem(index);
}

void MainWindow::on_button_removeAll_clicked()
{
	ui->list_send->clear();
}

void MainWindow::on_pushButton_clicked()
{

}

void MainWindow::OnProgressButtonClicked()
{
	if (ui->list_fileList->isHidden())
		ui->list_fileList->show();

	else
		ui->list_fileList->hide();
}

void MainWindow::ExitMenuClicked()
{
	_exit = true;
	close();
}

void MainWindow::SettingMenuClicked()
{
	if (_setting->isHidden())
		_setting->show();
}

void MainWindow::on_comboBox_activated(QString str)
{
	ui->list_connect->clear();
	QStringList list;
	CLIENT_MANAGER->GetDisplayedNames(str, list);
	for (int i = 0; i < list.count(); i++)
		ui->list_connect->addItem(list.at(i));

	//Todo : member count
	ui->label_memCnt->setText(QString::number(CLIENT_MANAGER->GetGroupMemberCount(str)));
}

void MainWindow::on_button_sSend_clicked()
{
	if (ui->list_send->count())
	{
		QString groupName;
		QHostAddress addr;
		QString with;
		for (int j = 0; j < ui->list_send->count(); j++)
			with += (ui->list_send->item(j)->text() + ',');
		QByteArray packet = _enc->fromUnicode(_textEditor->MessageTextProcessing(true,
																				ui->textEdit_send->toPlainText(),
																				CONFIG_MANAGER->GetGroupName(),
																				with,
																				_fileName));
		for (int i = 0; i < ui->list_send->count(); i++)
		{
			addr == QHostAddress::Null;
			groupName = ui->list_send->item(i)->text();
			if (CLIENT_MANAGER->IsValidClient(groupName))
				addr = CLIENT_MANAGER->GetAddress(groupName);
			if (addr != QHostAddress::Null)
			{
				if (_isfileSend)
				{
					emit sigAddSendTask(addr, _filePath);
					OnError("File transfer started");
				}
				QTcpSocket *socket = new QTcpSocket;
				socket->connectToHost(addr, MSG_PORT);
				socket->write(packet);
				socket->disconnectFromHost();
			}
		}
		//add log......
		if (_logManager->AddLog(QString(packet), true))
		{
			int idx = _logManager->GetLogCount(true);
			ManageLogWidget(true, idx, idx, false);
		}
		else
			OnError("Add log failed");
	}
	else
		QMessageBox::warning(this, "warning", "Addressee is not seleted.");
	ui->textEdit_send->clear();
	if (ui->button_rDelFlag->text() == "YES")
		ui->list_send->clear();
	ui->list_send->clear();
	if (_isfileSend)
	{
		_isfileSend = false;
		_filePath = "";
		_fileName = "";
		ui->list_sendFile->clear();
	}
}

void MainWindow::on_button_reply_clicked()
{
	QString rawData = ui->textEdit_receive->toPlainText();
	if (!rawData.isEmpty())
	{
		int index = rawData.indexOf('\n');
		QString replyForm = rawData;
		replyForm.resize(index);
		ui->list_send->addItem(replyForm);

		QString replyTime = rawData.mid(index + 1, 16);
		replyTime += QString(trUtf8(")에답장\n"));

		replyForm.push_front('>');
		replyForm += replyTime;
		ui->textEdit_send->setText(replyForm);

		QTextCursor cur = ui->textEdit_send->textCursor();
		cur.movePosition(QTextCursor::End);
		ui->textEdit_send->setTextCursor(cur);
	}
}

void MainWindow::on_button_rDelete_clicked()
{
	int idx = ui->label_rcvIndex->text().toInt();
	if (idx > 0)
	{
		//DeleteLog..
		_logManager->DeleteLog(false, idx);
		idx--;
		ManageLogWidget(false, idx, _logManager->GetLogCount(false), true);
	}
}

void MainWindow::on_button_sDelete_clicked()
{
	int idx = ui->label_sendIndex->text().toInt();
	if (idx > 0)
	{
		//DeleteLog..
		_logManager->DeleteLog(true, idx);
		idx--;
		ManageLogWidget(true, idx, _logManager->GetLogCount(true), true);
	}
}

void MainWindow::on_button_rPrevious_clicked()
{
	int idx = ui->label_rcvIndex->text().toInt();
	if (idx > 1)
	{
		idx--;
		ManageLogWidget(false, idx, _logManager->GetLogCount(false), true);
	}
}

void MainWindow::on_button_rNext_clicked()
{
	int idx = ui->label_rcvIndex->text().toInt();
	int sum = _logManager->GetLogCount(false);
	if (idx < sum)
	{
		idx++;
		ManageLogWidget(false, idx, sum, true);
	}
}

void MainWindow::on_button_rFirst_clicked()
{
	int idx = ui->label_rcvIndex->text().toInt();
	if (idx > 1)
	{
		idx = 1;
		ManageLogWidget(false, idx, _logManager->GetLogCount(false), true);
	}
}

void MainWindow::on_button_rLatest_clicked()
{
	int idx = ui->label_rcvIndex->text().toInt();
	int sum = ui->label_rcvSum->text().toInt();
	if (idx < sum)
	{
		idx = sum;
		ManageLogWidget(false, idx, sum, true);
	}
}

void MainWindow::on_button_sPrevious_clicked()
{
	int idx = ui->label_sendIndex->text().toInt();
	if (idx > 1)
	{
		idx--;
		ManageLogWidget(true, idx, _logManager->GetLogCount(true), true);
	}
}

void MainWindow::on_button_sNext_clicked()
{
	int idx = ui->label_sendIndex->text().toInt();
	int sum = _logManager->GetLogCount(true);
	if (idx < sum)
	{
		idx++;
		ManageLogWidget(true, idx, sum, true);
	}
}

void MainWindow::on_button_sFirst_clicked()
{
	int idx = ui->label_sendIndex->text().toInt();
	if (idx > 1)
	{
		idx = 1;
		ManageLogWidget(true, idx, _logManager->GetLogCount(true), true);
	}
}

void MainWindow::on_button_sLatest_clicked()
{
	int idx = ui->label_sendIndex->text().toInt();
	int sum = ui->label_sendSum->text().toInt();
	if (idx < sum)
	{
		idx = sum;
		ManageLogWidget(true, idx, sum, true);
	}
}

void MainWindow::on_button_fileSend_clicked()
{
	if (_fileSelect->isHidden())
		_fileSelect->show();
}

void MainWindow::on_button_refresh_clicked()
{
	if (UDP_RECEIVER->Bind(CONFIG_MANAGER->GetNetworkPort())) //rebind..
	{
		RefreshWidget();
		CLIENT_MANAGER->RemoveAllClients();
		_udpSender->SendDatagram(QString(';' + CONFIG_MANAGER->GetGroupName()).toAscii());
	}
	else
		OnError("Rebind failed");
}

void MainWindow::on_list_sendFile_itemDoubleClicked(QListWidgetItem* /*item*/)
{
	ui->list_sendFile->clear();
	ui->list_sendFile->hide();
	_isfileSend = false;
}

void MainWindow::on_button_ipName_clicked()
{
	if (_ipName->isHidden())
		_ipName->show();
}

void MainWindow::on_button_rDelFlag_clicked()
{
	if (ui->button_rDelFlag->text() == "No")
		ui->button_rDelFlag->setText("Yes");
	else
		ui->button_rDelFlag->setText("No");
}

void MainWindow::on_button_rFix_clicked()
{
	if (_fixedView)
	{
		ui->button_rFix->setText("NF");
		int idx = ui->label_rcvSum->text().toInt();
		ManageLogWidget(false, idx, _logManager->GetLogCount(false), false);
		_fixedView = false;
	}
	else
	{
		ui->button_rFix->setText("F");
		ui->button_rFirst->setDisabled(true);
		ui->button_rPrevious->setDisabled(true);
		ui->button_rNext->setDisabled(true);
		ui->button_rLatest->setDisabled(true);
		ui->button_rDelete->setDisabled(true);
		ui->button_rDeleteAll->setDisabled(true);
		_fixedView = true;
		//Todo : disable all buttons..
	}
}


void MainWindow::on_button_sDeleteAll_clicked()
{
	_logManager->DeleteLog(true);
	ManageLogWidget(true, 0, _logManager->GetLogCount(true), false);
}

void MainWindow::on_button_rDeleteAll_clicked()
{
	_logManager->DeleteLog(false);
	ManageLogWidget(false, 0, _logManager->GetLogCount(false), false);
}

void MainWindow::on_button_saveGroup_clicked()
{
	if (ui->list_send->count())
	{
		QString gName = QInputDialog::getText(this, "Input group name..", "Group Name");
		if (!gName.isEmpty())
		{
			QString groupList;
			for (int i = 0; i < ui->list_send->count(); i++)
			{
				groupList.append(ui->list_send->item(i)->text());
				if (i < ui->list_send->count()-1)
					groupList.append('\n');
			}
			CONFIG_MANAGER->SaveToFile(QString(QString("../conf/group/" + gName).toUtf8()), groupList.toUtf8().data());
			_groupList->Update();
		}
	}
}

void MainWindow::on_button_loadGroup_clicked()
{
	//Todo : open dialog..
	_groupList->show();
}

void MainWindow::on_button_moveWithList_clicked()
{

}
